\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{pcalendar}
\def\PCLD@classtoload{extarticle}
\RequirePackage{kvoptions}
\RequirePackage[dvipsnames,svgnames]{xcolor}
\RequirePackage{cncolours}
\SetupKeyvalOptions{family=PCLD, prefix=PCLD@, setkeys=\kvsetkeys}
\DeclareBoolOption[true]{prevnext}
\DeclareBoolOption[true]{sundayweek}
\DeclareOption*{\PassOptionsToClass{\CurrentOption}{\PCLD@classtoload}}
\ProcessKeyvalOptions{PCLD}
\ProcessOptions\relax
\LoadClass{\PCLD@classtoload}
%------------------------------------------------------------------
% 年、月、日、星期翻译作中文
%------------------------------------------------------------------
\RequirePackage{translator}
\deftranslation{January}{一月}
\deftranslation{February}{二月}
\deftranslation{March}{三月}
\deftranslation{April}{四月}
\deftranslation{May}{五月}
\deftranslation{June}{六月}
\deftranslation{July}{七月}
\deftranslation{August}{八月}
\deftranslation{September}{九月}
\deftranslation{October}{十月}
\deftranslation{November}{十一月}
\deftranslation{December}{十二月}
\deftranslation{Sunday}{日}
\deftranslation{Monday}{一}
\deftranslation{Tuesday}{二}
\deftranslation{Wednesday}{三}
\deftranslation{Thursday}{四}
\deftranslation{Friday}{五}
\deftranslation{Saturday}{六}
%------------------------------------------------------------------
% 日历排列方式设定
%------------------------------------------------------------------
\ifPCLD@sundayweek
  \def\@daynumlist{0/6,1/0,2/1,3/2,4/3,5/4,6/5}
  \def\@weekstyle{week list sunday}
\else
  \def\@daynumlist{0/0,1/1,2/2,3/3,4/4,5/5,6/6}
  \def\@weekstyle{week list}
\fi
%------------------------------------------------------------------
% 基本长度设置
%------------------------------------------------------------------
\newlength{\CalPageMargin}
\newlength{\EventLineWidth}
\setlength{\CalPageMargin}{1cm}
\setlength{\EventLineWidth}{6in}
\setlength{\parindent}{0pt}
\setlength{\parskip}{0pt}
%------------------------------------------------------------------
% 初始宏设置
%------------------------------------------------------------------
\def\@coverBgColor{white}
\def\@coverImage{}
\def\@coverImageCaption{}
\def\@coverTitleText{2020 日历}
\def\@sundayColor{red}
\def\@saturdayColor{green}
\def\@eventStyle{}
\def\@eventlist{}
\def\eventSep{：}
%------------------------------------------------------------------
% 页面设置
%------------------------------------------------------------------
\RequirePackage{geometry}
\geometry{
  paperwidth=  350mm,
  paperheight= 200mm,
  margin=\CalPageMargin
}
\RequirePackage{pgfpages}
%------------------------------------------------------------------
% 字体设置
%------------------------------------------------------------------
\RequirePackage{ctex}
\RequirePackage{fontawesome5}
\newcommand{\MyHeart}{\faHeart[regular]}
\setmainfont{EB Garamond}[%
  Ligatures=TeX,
  Numbers=Lining
]
\setsansfont{Fira Sans Light}[%
  Ligatures=TeX,
  BoldItalicFont=Fira Sans Italic,
  BoldFont=Fira Sans,
  Numbers=Lining
]
% \setCJKsansfont{Noto Sans CJK SC}
% \newCJKfontfamily\zhnoto{Noto Sans CJK SC}

\newfontfamily\heros{texgyreheros}[
  Extension = {.otf},
  UprightFont = {*-regular}, ItalicFont = {*-italic},
  BoldFont = {*-bold}, BoldItalicFont = {*-bolditalic},
]
%------------------------------------------------------------------
% 加载宏包
%------------------------------------------------------------------
\RequirePackage{ifxetex}
\RequirePackage{csvsimple,xstring}
\RequirePackage{tikz}
\usetikzlibrary{calendar,positioning,backgrounds,shapes}
\RequirePackage[useregional,showdow]{datetime2}
\DTMlangsetup{abbr,ord=raise,showyear=false}
\RequirePackage{regexpatch}
\RequirePackage{xargs}
\RequirePackage{pgfkeys}
\RequirePackage[absolute,overlay]{textpos}
\RequirePackage[nopagecolor=white,pagecolor=white]{pagecolor}
\RequirePackage{scrlfile}
\RequirePackage{qrcode,url}
%------------------------------------------------------------------
% tikz 一般设置
%------------------------------------------------------------------
\tikzset{
  % 周日字头样式
  sunHeadingsOptions/.style={
    font=\sffamily\bfseries,
    \@sundayColor
  },
  % 周六字头样式
  satHeadingsOptions/.style={
    font=\sffamily\bfseries,
    \@saturdayColor
  },
  % 月份标题样式
  monthTitleOptions/.style={
    font={\fontsize{40pt}{42pt}\bfseries\itshape\heros}, red!50!RedViolet
  },
  % 封面标题样式
  coverTitleOptions/.style={
    font=\Huge\sffamily
  },
  dayHeadingsOptions/.style={
    font=\sffamily\bfseries,
    gray!90
  },
  default mark/.style={circle,draw=red!50},
  holiday/.style={
    rectangle,
    fill=orange!40,
    inner xsep=1.375em,
    inner ysep=0.5em
  },
  winter/.style={
    rectangle,
    fill=SkyBlue!50,
    inner xsep=1.375em,
    inner ysep=0.5em
  },
  summer/.style={
    rectangle,
    fill=Goldenrod!50,
    inner xsep=1.375em,
    inner ysep=0.5em
  },
  red icon/.style={
    text=red!40,
    font=\large
  },
  pink icon/.style={
    text=Pink,
    font=\large
  },
  blue icon/.style={
    text=MidnightBlue!40,
    font=\large
  },
  green icon/.style={
    text=ForestGreen!80,
    font=\large
  },
  shopping/.style={
    text=Goldenrod,font=\large},
  international/.style={text=OliveGreen!50,font=\large},
}
%------------------------------------------------------------------
% tikz 样式设置 Code from http://tex.stackexchange.com/a/10199/226
%------------------------------------------------------------------
% 主月历的星期标志，判断周六周日采用不同的颜色表示
\tikzstyle{day letter headings}=[
    execute before day scope={ \ifdate{day of month=1}{%
      \pgfmathsetlength{\pgf@ya}{\tikz@lib@cal@yshift}%
      \pgfmathsetlength\pgf@xa{\tikz@lib@cal@xshift}%
      \pgftransformyshift{-\pgf@ya}
      \foreach \n/\d in \@daynumlist {
        \def\theD{\pgfcalendarweekdayname{\d}}
        \pgf@xa=\n\pgf@xa%
        \pgftransformxshift{\pgf@xa}%
        \pgftransformyshift{\pgf@ya}%
        \ifnum\d<5
          \node[every day,dayHeadingsOptions]{\theD};%
        \else
          \ifnum\d<6
            \node[every day,satHeadingsOptions]{\theD};
          \else
            \node[every day,sunHeadingsOptions]{\theD};
          \fi
        \fi
      }
    }{}%
  }%
]
% 前后月小月历的星期标志
\tikzstyle{small day letter headings}=[
  execute before day scope={%
    \ifdate{day of month=1}{%
      \pgfmathsetlength{\pgf@ya}{\tikz@lib@cal@yshift}%
      \pgfmathsetlength\pgf@xa{\tikz@lib@cal@xshift}%
      \pgftransformyshift{-\pgf@ya}
      \foreach \n/\d in \@daynumlist{%
        \def\theD{\pgfcalendarweekdayname{\d}}
        \pgf@xa=\n\pgf@xa%
        \pgftransformxshift{\pgf@xa}%
        \pgftransformyshift{\pgf@ya}%
        \node[every day,dayHeadingsOptions]{\theD};
      }
    }{}%
  }%
]
% 每周从周日开始
\tikzstyle{week list sunday}=[
  execute before day scope={%
    \ifdate{day of month=1}{\ifdate{equals=\pgfcalendarbeginiso}{}{
      \pgfmathsetlength{\pgf@y}{\tikz@lib@cal@month@yshift}%
      \pgftransformyshift{-\pgf@y}
    }}{}%
  },
  execute at begin day scope={%
    \pgfmathsetlength\pgf@x{\tikz@lib@cal@xshift}%
    \ifnum\pgfcalendarcurrentweekday=6
      \c@pgf@counta=0
    \else
      \c@pgf@counta=\pgfcalendarcurrentweekday
      \advance\c@pgf@counta by 1
    \fi
    \pgf@x=\c@pgf@counta\pgf@x
    \pgftransformxshift{\pgf@x}
  },
  execute after day scope={
    % Week is done, shift to the next line.
    \ifdate{Saturday}{
      \pgfmathsetlength{\pgf@y}{\tikz@lib@cal@yshift}%
      \pgftransformyshift{-\pgf@y}
    }{}%
  },
  tikz@lib@cal@width=7
]
%------------------------------------------------------------------
% pgfkey 设置
%------------------------------------------------------------------
\pgfkeys{
  /eventmark/.is family, /eventmark,
  default/.style = {
    marker = {},
    mark style = {}
  },
  marker/.store in = \event@marker,
  mark style/.store in = \event@markstyle
}%
%------------------------------------------------------------------
% 对月份的名称不进行翻译
%------------------------------------------------------------------
\let\xpgfcalendarmonthname\pgfcalendarmonthname
\xpatchcmd{\xpgfcalendarmonthname}
      {\pgfutil@translate}
      {\relax}
      {}{}
%------------------------------------------------------------------
% 对中国农历的应用
%------------------------------------------------------------------
\newcommand{\annotdate}[2]{%
  \ifboolexpr{ test{\IfBeginWith{#2}{初}}
            or test{\IfBeginWith{#2}{十}}
            or test{\IfEndWith{#2}{十}}
            or test{\IfBeginWith{#2}{廿}}
  }{\def\extra{}}%
   {\def\extra{red!70!black}}%
  \node[font=\tiny\bfseries\sffamily\CJKspace,\extra,
  anchor=north,outer sep=0.55ex,align=flush center]
  at (cdCal-\thepage-#1) {#2};%
}
\newcommand{\importlunar}[2][2020]{%
\begin{scope}[on background layer]%
  \csvreader[filter test=\IfBeginWith{\LNDATE}{#1-#2}]
  {lunar-#1.csv}{EVENT=\LNEVENT,DATE=\LNDATE}
  {\annotdate{\LNDATE}{\LNEVENT}}
\end{scope}%
}
%------------------------------------------------------------------
% 用户命令
%------------------------------------------------------------------
\newcommand\printeventname[1]{\textbf{#1}}
\newcommand\coverBgColor[1]{\def\@coverBgColor{#1}}
\newcommand\coverImage[1]{\def\@coverImage{#1}}
\newcommand\coverTitle[2][]{
  \notblank{#1}{\tikzset{coverTitleOptions/.style={#1}}}{}
  \def\@coverTitleText{#2}
}
\newcommand\makeCover{%
  \begingroup%
  \ifnum\pgf@logicalpages=0\relax
    \pagecolor{\@coverBgColor}%
  \else
    \ifx\@Gm@driver\@Gm@dvipdfm
      \typeout{I see you dvipdfm}
      \tikz[remember picture,overlay]
      \fill[\@coverBgColor] (current page.north west) rectangle (current page.south east);%
    \else
      \pagecolor{\@coverBgColor}%
    \fi%
  \fi%
  \ifdefempty{\@coverImage}{}{%
    \begin{textblock*}{\paperwidth}(0pt,0pt)%
    \tikz\node[inner sep=0pt] {%
      \includegraphics[width=\paperwidth]{\@coverImage}
      };
  \end{textblock*}}
  \begin{textblock*}{\paperwidth}[1,1](\dimexpr\paperwidth-5ex\relax,\dimexpr\paperheight-5ex\relax)
    \noindent\tikz\node[coverTitleOptions,inner sep=0pt] {\@coverTitleText};
  \end{textblock*}
  \endgroup\null\clearpage\nopagecolor\normalsize%
}
\newcommand\sundayColor[1]{\def\@sundayColor{#1}}
\newcommand\saturdayColor[1]{\def\@saturdayColor{#1}}
\newcommand\eventStyle[1]{\def\@eventStyle{#1}}
\newcommand\dayHeadingStyle[1]{
  \tikzset{dayHeadingsOptions/.style={#1}}
}
\newcommand\monthTitleStyle[1]{
  \tikzset{monthTitleOptions/.style={#1}}
}
\newcommand{\printdate}[1]{\DTMdate{#1}}
\newenvironment{monthCalendar}[2]{%
  \begin{textblock*}{\textwidth}[0,1](\CalPageMargin,\paperheight-\CalPageMargin)
    \raggedleft\scriptsize\color{black!70}
    \begin{tikzpicture}
      \node[rotate=0,transform shape,monthTitleOptions, inner sep=0pt] (mainMonthHead)
      {\xpgfcalendarmonthname{#2} #1};
      \ifPCLD@prevnext
        \begingroup%
        \tikzset{
          every calendar/.append style={
            day yshift=1.5em,
            month label above centered,
            \@weekstyle,
            day xshift=1.8em,
            small day letter headings
          },
      dayHeadingsOptions/.style={font=\sffamily\bfseries,gray!90},
      every day/.append style={align=center,font={\mdseries\sffamily},text width=2em},every month/.append style={font=\sffamily\mdseries}}
      \pgfmathsetmacro{\tmppremonth}{int(\number#2-1)}%
      \pgfmathsetmacro{\tmppostmonth}{int(\number#2+1)}%
    \matrix[row sep=2.0em,matrix anchor=south west,
    right=2cm of mainMonthHead.south east,
    ampersand replacement=\&,column sep =2em]{%
      \calendar [dates=#1-\tmppremonth-01 to #1-\tmppremonth-last];\&
      \calendar [dates=#1-\tmppostmonth-01 to #1-\tmppostmonth-last];\\
    };
    \endgroup\fi
  \end{tikzpicture}
  \end{textblock*}%
  \begin{textblock*}{\textwidth}[0,1](0.67\paperwidth,\paperheight-5.5cm)
  \noindent\begin{tikzpicture}[remember picture]
  \calendar (cdCal-\thepage) [
    dates=#1-#2-01 to #1-#2-last,
    month text = {\%mt \%y-},
    inner sep=\CalPageMargin,
    \@weekstyle,
    day xshift=2.2em,day yshift=2.5em,
    every day/.append style={text height=1.5ex,text depth=0.25ex,text width=1.5em,align=flush center,font={\bfseries}},
    day letter headings
    ]
    if (Sunday) [\@sundayColor] if (Saturday) [\@saturdayColor];
  \end{tikzpicture}
  \end{textblock*}%
%
  \gdef\@eventlist{}%
%
    \begin{tikzpicture}[remember picture,overlay]
%
    \newcommand{\markCalendar}[2][]{%
      \pgfkeys{/eventmark,default,##1}%
      \DTMsavedate{tmp}{##2}%
      \@ifundefined{pgf@sh@ns@cdCal-\thepage-##2}{}{%
        \begin{scope}[on background layer]
        \node[inner sep=1.25ex,\event@markstyle]
          at (cdCal-\thepage-##2) {\event@marker};%
        \end{scope}%
      }%
    }
%
    % #1=style; #2=startdate; #3=enddate or days; #4=name
    \newcommand{\event}[4][mark style=default mark]{%
      \ifblank{##3}{\oneDayEvent[##1]{##2}{##4}}{%
        \ifboolexpr{ test {\ifstrequal{##2}{##3}}
                  or test {\ifdefequal{##2}{##3}}
                  or test {\ifdefstring{##3}{1}}}
                   {\oneDayEvent[##1]{##2}{##4}}%
                   {\multiDayEvent[##1]{##2}{##3}{##4}}%
        }%
    }
%
    % #1=style; #2=startdate; #4=name
    \newcommand{\oneDayEvent}[3][mark style=default mark]{%
      \pgfkeys{/eventmark,default,##1}%
      \markCalendar[##1]{##2}%
      \protected@xappto{\@eventlist}{%
        \makebox[1.75em][c]{\protect\tikz%
          \protect\node[\event@markstyle,font=\fontsize{1em}{1em},%
          \ifdefempty{\event@marker}{inner sep=0.5ex}{inner sep=0pt},
  ]{\event@marker};}%
        \printeventname{##3\eventSep}\DTMdate{##2}\par%
      }{}{}
    }
%
    % #1=style; #2=startdate; #3=enddate or days; #4=name
    \newcommand{\multiDayEvent}[4][mark style=default mark]{%
      \IfInteger{##3}%
        {\multiDayEventWithDuration[##1]{##2}{##3}{##4}}%
        {\multiDayEventWithEnd[##1]{##2}{##3}{##4}}%
    }
%
    % #1=style; #2=startdate; #3=days; #4=name
    \newcommand{\multiDayEventWithDuration}[4][mark style=default mark]{%
      \pgfkeys{/eventmark,default,##1}%
      \pgfmathparse{##3-1}%
      \foreach \d in {0,...,\pgfmathresult}{%
      	\DTMsavedate{tmp}{##2+\d}%
        \DTMmakeglobal{tmp}%
      	\markCalendar[##1]{\DTMfetchyear{tmp}-\DTMfetchmonth{tmp}-\DTMfetchday{tmp}}%
      }%
      \protected@xappto{\@eventlist}{%
        \makebox[1.75em][c]{\protect\tikz%
          \protect\node[\event@markstyle,font=\fontsize{1em}{1em},%
          \ifdefempty{\event@marker}{inner sep=0.5ex}{inner sep=0pt},%
          ]{\event@marker};}%
        \printeventname{##4\eventSep}\DTMdate{##2}\,--\,\DTMusedate{tmp}\par}{}{}%
    }
%
    % #1=style; #2=startdate; #3=enddate; #4=name
    \newcommand{\multiDayEventWithEnd}[4][mark style=default mark]{%
      \DTMsavedate{startdate}{##2}%
      \DTMsavedate{enddate}{##3+1}%
      \newcount\myct%
      \DTMsaveddatediff{enddate}{startdate}{\myct}%
      \multiDayEventWithDuration[##1]{##2}{\myct}{##4}%
    }
}{%
  \end{tikzpicture}%
  \begin{textblock*}{\textwidth}(0.69\paperwidth,\CalPageMargin)
  %\rule{0.5\paperwidth}{0pt}
  \begin{minipage}{\EventLineWidth}\@eventStyle%
  \setlength{\parskip}{0.5ex}%
  \@eventlist%
  \end{minipage}%
  \end{textblock*}
}
\def\qrbox{\fbox{\qrcode[height=25mm]{http://weixin.qq.com/r/9kylvQfEA1p8rUPe9xnk}}}

\NewDocumentCommand{\QRCodeURL}{ O{25mm} v }{
  \def\qrbox{\fbox{\qrcode[height=#1]{#2}}}
}

\NewDocumentCommand\illustration{ O{} m m }{
  \newpage
  \tikz\node [rectangle split, rectangle split parts=2,
    rectangle split part align={left,left},
    text width=0.67\textwidth,inner xsep=0pt,inner ysep=3pt,font=\slshape\footnotesize]
    {\includegraphics[width=\textwidth]{#3}\nodepart{second} #1\hfill #2};\par\vfill {\color{darkgray}\qrbox}
}

% \newcommand{\illustration}[2][]{%
%   \newpage
%   \tikz\node [rectangle split, rectangle split parts=2,
%     rectangle split part align={left,left},
%     text width=0.67\textwidth,inner xsep=0pt,inner ysep=3pt,font=\itshape\tiny]
%     {\includegraphics[width=\textwidth]{#2}\nodepart{second} #1};\par\vfill 123
% }
\newcommand{\backCalendar}[2]{%
  \newpage
  \begin{tikzpicture}[remember picture,overlay]
    \node [inner sep=\CalPageMargin]
    at (current page.north east)[below left]{%
    \includegraphics[height=\paperheight-\CalPageMargin-\CalPageMargin]{#2a}};
  \end{tikzpicture}
  \begin{tikzpicture}
    \calendar [
      dates=#1-#2-01 to #1-#2-last,
      month text = {\%mt \%y-},
      inner sep=\CalPageMargin,
      \@weekstyle,
      day xshift=3.80em,day yshift=4.0em,
      day code={\node[rectangle,rounded corners =15pt ,draw=black,name=\pgfcalendarsuggestedname, every day,outer sep=0pt]{\tikzdaytext};},
      every day/.append style=
        {
          text height=1.5ex,
          text depth=0.25ex,
          text width=0.5em,
          align=flush center,
          font={\bfseries\sffamily
          }
        },
      day letter headings
      ]
      if (Sunday) [\@sundayColor] if (Saturday) [\@saturdayColor];
  \end{tikzpicture}
}
%------------------------------------------------------------------
% 基本设置
%------------------------------------------------------------------
\AtBeginDocument{\renewcommand*{\DTMdisplaydate}[4]{\number#2~月~\number#3~日}}
\robustify{\\}
\pagestyle{empty}
\endinput


